fix(providers): qwen-web model discovery lists live catalog (#3931) - #4172
Conversation
qwen-web (cookie provider) had no PROVIDER_MODELS_CONFIG entry, so its model- discovery page returned an empty/stale local catalog — the OAuth fallback at the top of the route only fires for provider===qwen, so qwen-web fell through to the no-config branch. Added a qwen-web entry that fetches the public https://chat.qwen.ai/api/v2/models endpoint (no auth header configured/sent) and parses the { data: { data: [{ id, name, owned_by }] } } shape, with a flatter { data: [] } fallback. This is Problem #3 of #3931 (diagnosed by @thezukiru). Problem #1 (validator bare-token false-positive) shipped earlier in the merged PR #3958; Problem #2 (empty stream from Qwen WAF bot-detection on the streaming endpoint) is a separate upstream/stealth concern and stays open. TDD: tests/unit/qwen-web-models-discovery-3931.test.ts mocks the upstream and asserts source==='api' + the live ids (and the flatter shape), RED 0/2 -> GREEN 2/2. Rebaselined route.ts 2512->2531. Co-authored-by: thezukiru <thezukiru@users.noreply.github.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
Code Review
This pull request adds model discovery support for the qwen-web cookie provider by adding an entry to PROVIDER_MODELS_CONFIG that fetches from the public Qwen models endpoint, along with corresponding unit tests. The reviewer suggested adding a safety filter to the response parser to prevent potential runtime exceptions when mapping over non-object or null elements in the returned data.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| return (Array.isArray(innerData) ? innerData : []) | ||
| .map((item: any) => ({ | ||
| id: item.id || item.name, | ||
| name: item.name || item.id, | ||
| owned_by: item.owned_by || "qwen", | ||
| })) | ||
| .filter((m: any) => m.id); |
There was a problem hiding this comment.
To prevent potential runtime exceptions (e.g., TypeError: Cannot read properties of null), it is safer to filter out any non-object or null elements from innerData before mapping over them.
return (Array.isArray(innerData) ? innerData : [])
.filter((item: any) => item && typeof item === "object")
.map((item: any) => ({
id: item.id || item.name,
name: item.name || item.id,
owned_by: item.owned_by || "qwen",
}))
.filter((m: any) => m.id);…iscovery (#3931 bug 3, #3737) (#4185) Integrated into release/v3.8.29 — add moonshotai/kimi-k2.7-code to the kmca (kimi-coding-apikey) catalog (KIMI_CODING_SHARED.models), requested in discussion #3737. On resync: the PR's qwen-web PROVIDER_MODELS_CONFIG addition (issue #3931 bug #3) was already shipped by #4172 — dropped the duplicate, kept release's entry (which has the Array.isArray guard); kept #4183's KIMI_K27_MODELS spread + added the moonshotai-prefixed entry (union). Also reconciled the file-size baseline for openai-to-gemini.ts (#4180 merged without its +20 bump). Validated: 13/13 tests (kmca catalog + qwen-web parse + kimi registration) + file-size green.
…zapw#3931) (diegosouzapw#4172) qwen-web (cookie provider) had no PROVIDER_MODELS_CONFIG entry, so its model- discovery page returned an empty/stale local catalog — the OAuth fallback at the top of the route only fires for provider===qwen, so qwen-web fell through to the no-config branch. Added a qwen-web entry that fetches the public https://chat.qwen.ai/api/v2/models endpoint (no auth header configured/sent) and parses the { data: { data: [{ id, name, owned_by }] } } shape, with a flatter { data: [] } fallback. This is Problem diegosouzapw#3 of diegosouzapw#3931 (diagnosed by @thezukiru). Problem diegosouzapw#1 (validator bare-token false-positive) shipped earlier in the merged PR diegosouzapw#3958; Problem diegosouzapw#2 (empty stream from Qwen WAF bot-detection on the streaming endpoint) is a separate upstream/stealth concern and stays open. TDD: tests/unit/qwen-web-models-discovery-3931.test.ts mocks the upstream and asserts source==='api' + the live ids (and the flatter shape), RED 0/2 -> GREEN 2/2. Rebaselined route.ts 2512->2531. Co-authored-by: thezukiru <thezukiru@users.noreply.github.com>
…iscovery (diegosouzapw#3931 bug 3, diegosouzapw#3737) (diegosouzapw#4185) Integrated into release/v3.8.29 — add moonshotai/kimi-k2.7-code to the kmca (kimi-coding-apikey) catalog (KIMI_CODING_SHARED.models), requested in discussion diegosouzapw#3737. On resync: the PR's qwen-web PROVIDER_MODELS_CONFIG addition (issue diegosouzapw#3931 bug diegosouzapw#3) was already shipped by diegosouzapw#4172 — dropped the duplicate, kept release's entry (which has the Array.isArray guard); kept diegosouzapw#4183's KIMI_K27_MODELS spread + added the moonshotai-prefixed entry (union). Also reconciled the file-size baseline for openai-to-gemini.ts (diegosouzapw#4180 merged without its +20 bump). Validated: 13/13 tests (kmca catalog + qwen-web parse + kimi registration) + file-size green.
Addresses Problem #3 of #3931 (diagnosed by @thezukiru in discussion #3895).
Problem
The
qwen-webcookie provider had no entry inPROVIDER_MODELS_CONFIG(src/app/api/providers/[id]/models/route.ts), so its model-discovery page returned an empty/stale local catalog. The OAuth fallback at the top of the handler only fires forprovider === "qwen" && authType === "oauth", soqwen-webfell straight through to the no-config branch (source: "local_catalog").Fix
Added a
qwen-webPROVIDER_MODELS_CONFIGentry that fetches the publichttps://chat.qwen.ai/api/v2/modelsendpoint (no auth header configured/sent) and parses the real shape{ data: { data: [{ id, name, owned_by }] } }, with a flatter{ data: [] }fallback. Exactly the entry @thezukiru/the maintainer specified on the issue.Scope
This is only Problem #3. The issue tracks three:
/api/v2/chat/completions— separate upstream/stealth concern (browser works, headless blocked), stays open;PROVIDER_MODELS_CONFIG.So #3931 stays open after this lands (Problem #2 remains).
Test (TDD, Hard Rule #18)
tests/unit/qwen-web-models-discovery-3931.test.tsmocks the upstream and drives the real route (modelsRoute.GET), assertingsource === "api", thechat.qwen.ai/api/v2/modelsprobe, and the parsed live ids — plus the flatter{ data: [] }shape. RED 0/2 → GREEN 2/2. Provider-models route regression 64/64. typecheck:core, eslint, check:file-size clean (rebaselined route.ts 2512→2531).